package com.bvgol.examples.nio.niosocket;/**
 * @Classname TestNIOServer
 * @Description TODO
 * @Date 2021/6/21 9:30
 * @Created by GUOCHEN
 */

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @program: my-spring-completely
 * @description:
 * @author: GUOCHEN
 * @create: 2021/06/21 09:30
 */
public class TestNIOServer {
    public static void startServer() {
        try {
            //ServerSocketChannel api 看看
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            Selector selector = Selector.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(6666));

            //设置为非阻塞
            serverSocketChannel.configureBlocking(false);

            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

            while (true) {

                //            if (selector.selectNow()==0) {
                //没有事件发生
                if (selector.select(1000) == 0) {
                    System.out.println("等待事件发生");
                    continue;
                }

                Set<SelectionKey> selectionKeys = selector.selectedKeys();

                Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();

                while (selectionKeyIterator.hasNext()) {
                    SelectionKey selectionKey = selectionKeyIterator.next();

                    //根据事件处理

                    if (selectionKey.isAcceptable()) {
                        try {
                            System.out.println("事件为 Accept");
                            SocketChannel socketChannel = serverSocketChannel.accept();

                            socketChannel.configureBlocking(false);

                            socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (selectionKey.isReadable()) {
                        System.out.println("事件为 Read");
                        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                        //获取buffer
                        ByteBuffer buffer = (ByteBuffer) selectionKey.attachment();

                        try {
                            socketChannel.read(buffer);
                            System.out.println("从客户端 " + new String(buffer.array()));

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    //手动移除当前的 selectionkey
                    selectionKeyIterator.remove();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws Exception {
        TestNIOServer.startServer();

    }
}
